#include "tableprintwidget.h"
#include "ui_tableprintwidget.h"
#include "liberweima/erweima.h"
#include "printer_pos_win_pos80.h"
#include "bmp_info.h"
#include "tableprintsettings.h"

QString tablePrintWidget::saveFilePath = "table_print_receipt.txt";
QString tablePrintWidget::fastfd_defaultSetting = "userdata/settings/print/table_receipt/def.txt";
QMap<QString, QVariant> tablePrintWidget::receipt_head = {
    {"logo",            "C:/Users/cz/Pictures/logo.png"},
//    {"first_title",     "Receipt"},
    {"second_title",    "qwqeafsdfsd"},
    {"tax_number",      "123456"},
    {"top",              "新开小店，欢迎品尝商家地址：南京市栖霞区文苑路与学思路路口文苑广场"}//"Newsgd.com is the premier online source of Guangdong news and information, fully displaying Guangdong through channels including Guangdong News"}
};
QMap<QString, QVariant> tablePrintWidget::sale_head =   {  {"payno",       "P2112140100001"},
                                                           {"operid",      "0000"},
                                                           {"table",       "Q000"},
                                                           {"person",      "2"},
                                                           {"time",        "2021-12-14 13:22:35"},
                                                           {"serial_no",   "001"}
                                                        };
QMap<QString, QVariant> tablePrintWidget::sale_detail =
{
    //{"Key",           QStringList{"1", "2", "3", "4", "5"}},
    {"dishname",      QStringList{"Bas-Armagnac", "CRF-Rsv", "Demandis-XO", "Antiquissima-15a", "Cachaca-51"}},
    {"unit",          QStringList{"set", "set", "set", "set", "set"}},
    {"num",           QStringList{"1.00", "1.00", "1.00", "1.00", "1.00"}},
    {"price",         QStringList{"1.00", "2.00", "3.00", "4.00", "5.00"}},
    {"amount",        QStringList{"1.00", "2.00", "3.00", "4.00", "5.00"}},
    {"dishname_2",    QStringList{"Bas", "CRF", "Demandis", "Antiquissima", "Cachaca"}},
};
QMap<QString, QVariant> tablePrintWidget::sale_detail_content;
QMap<QString, QVariant> tablePrintWidget::pay_detail =
{{"num_cost",        "436.00"},
 {"num_present",     "0.00"},
 {"num_discount",    "0.00"},
 {"num_rate",        "64.00"},
 {"num_free",        "0.00"},

 {"num_blotout",     "0.00"},
 {"num_realamount",  "436.00"},
 {"num_amount",      "436.00"},
 {"num_change",      "0.00"}
};
QMap<QString, QVariant> tablePrintWidget::pay_detail_paymode = {{"Cash", "436.00"}};
QMap<QString, QVariant> tablePrintWidget::receipt_tail = {{"signature",    "Signature line:"},
                                                          {"qr_code",      "www.scpos.com"},
                                                          {"bottom",       "123456789"}
                                                         };
QMap<QString, QVariant> tablePrintWidget::receiptMap = {
    {"receipt_head",          QVariant::fromValue(receipt_head)},
    {"sale_head",             QVariant::fromValue(sale_head)},
    {"sale_detail",           QVariant::fromValue(sale_detail)},
    {"sale_detail_content",   QVariant::fromValue(sale_detail_content)},
    {"pay_detail",            QVariant::fromValue(pay_detail)},
    {"pay_detail_paymode",    QVariant::fromValue(pay_detail_paymode)},
    {"receipt_tail",          QVariant::fromValue(receipt_tail)}
};


QMap<QString, QVariant> tablePrintWidget::colorMap = {{"receipt_head", QColor("blue")},
                                                      {"sale_head", QColor("red")},
                                                      {"sale_detail", QColor("green")},
                                                      {"sale_detail_content", QColor("pink")},
                                                      {"pay_detail", QColor("yellow")},
                                                      {"pay_detail_paymode", QColor("black")},

                                                      {"receipt_tail", QColor("purple")},
                                                     };


QMap<QString, QString> tablePrintWidget::receiptTrans = {
    {"time", QObject::tr("时间")},
    {"payno", QObject::tr("单号")},
    {"num", QObject::tr("数量")},
    {"price", QObject::tr("价格")},
    {"num_free", QObject::tr("免费")},
};

QByteArray defaultSetting = R"(
                            {
                            "column_width0": 212,
                            "column_width1": 198,
                            "column_width2": 113,
                            "font": "Arial,18,-1,5,50,0,0,0,0,0",
                            "pay_detail": [
                            {
                            "align": 129,
                            "key": "num_amount",
                            "type": "",
                            "value": "num_amount",
                            "value2": "",
                            "value3": "436.00"
                            },
                            {
                            "align": 129,
                            "key": "num_present",
                            "type": "",
                            "value": "num_present",
                            "value2": "",
                            "value3": "0.00"
                            },
                            {
                            "align": 129,
                            "key": "num_free",
                            "type": "",
                            "value": "num_free",
                            "value2": "",
                            "value3": "0.00"
                            },
                            {
                            "align": 129,
                            "key": "num_cost",
                            "type": "",
                            "value": "num_free",
                            "value2": "",
                            "value3": "436.00"
                            }
                            ],
                            "pay_detail_paymode": [
                            {
                            "align": 129,
                            "key": "Cash",
                            "type": "",
                            "value": "Cash",
                            "value2": "",
                            "value3": "436.00"
                            }
                            ],
                            "receipt_head": [
                            {
                            "align": 132,
                            "key": "first_title",
                            "type": "",
                            "value": "Receipt",
                            "value2": "",
                            "value3": ""
                            }
                            ],
                            "receipt_tail": [
                            {
                            "align": 129,
                            "key": "signature",
                            "type": "",
                            "value": "Signature line:",
                            "value2": "",
                            "value3": ""
                            },
                            {
                            "align": 129,
                            "key": "qr_code",
                            "type": "qr_code",
                            "value": "www.scpos.com",
                            "value2": "www.scpos.com",
                            "value3": ""
                            }
                            ],
                            "sale_detail": [
                            {
                            "align": 129,
                            "key": "dishname",
                            "row": 0,
                            "type": "",
                            "value": "dishname",
                            "value2": "",
                            "value3": "",
                            "width": 250
                            },
                            {
                            "align": 129,
                            "key": "num",
                            "row": 0,
                            "type": "",
                            "value": "num",
                            "value2": "",
                            "value3": "",
                            "width": 80
                            },
                            {
                            "align": 129,
                            "key": "price",
                            "row": 0,
                            "type": "",
                            "value": "price",
                            "value2": "",
                            "value3": "",
                            "width": 80
                            },
                            {
                            "align": 129,
                            "key": "amount",
                            "row": 0,
                            "type": "",
                            "value": "amount",
                            "value2": "",
                            "value3": "",
                            "width": 120
                            },
                            {
                            "align": 129,
                            "key": "",
                            "row": 0,
                            "type": "",
                            "value": "",
                            "value2": "",
                            "value3": "",
                            "width": 125
                            }
                            ],
                            "sale_detail_content": [
                            {
                            "align": 129,
                            "key": "dishname",
                            "row": 0,
                            "type": "",
                            "value": "dishname",
                            "value2": "",
                            "width": 250
                            },
                            {
                            "align": 129,
                            "key": "num",
                            "row": 0,
                            "type": "",
                            "value": "num",
                            "value2": "",
                            "width": 80
                            },
                            {
                            "align": 129,
                            "key": "price",
                            "row": 0,
                            "type": "",
                            "value": "price",
                            "value2": "",
                            "width": 80
                            },
                            {
                            "align": 129,
                            "key": "amount",
                            "row": 0,
                            "type": "",
                            "value": "amount",
                            "value2": "",
                            "width": 120
                            },
                            {
                            "align": 129,
                            "key": "",
                            "row": 0,
                            "type": "",
                            "value": "",
                            "value2": "",
                            "width": 125
                            },
                            {
                            "align": 129,
                            "key": "",
                            "row": 0,
                            "type": "",
                            "value": "",
                            "value2": "",
                            "width": 125
                            }
                            ],
                            "sale_head": [
                            {
                            "align": 129,
                            "key": "memo",
                            "type": "",
                            "value": "memo",
                            "value2": "hello",
                            "value3": ""
                            },
                            {
                            "align": 129,
                            "key": "time",
                            "type": "",
                            "value": "time",
                            "value2": "2021-12-14 13:22:35",
                            "value3": ""
                            },
                            {
                            "align": 129,
                            "key": "times",
                            "type": "",
                            "value": "times",
                            "value2": "00:00:00",
                            "value3": ""
                            },
                            {
                            "align": 129,
                            "key": "payno",
                            "type": "",
                            "value": "payno",
                            "value2": "P2112140100001",
                            "value3": ""
                            }
                            ]
                            }


                            )";
#define rowHeight0  QFontMetrics(ui->tableWidget->font()).height()
#define rowGap 6
#define lineHeight (QFontMetrics(ui->tableWidget->font()).height() * 0.3)
#define buttonHeight 120

QPixmap get_rbcode(const char *string)
{
    //1
    QPixmap pixmap_rb;
    QRcode *qr = QRcode_encodeString(string,3, QR_ECLEVEL_L, QR_MODE_8, 1);
    if(0 != qr) {
        pixmap_rb = QPixmap(qr->width, qr->width);

        QPainter painter(&pixmap_rb);
        painter.fillRect(QRect(0, 0, pixmap_rb.width(), pixmap_rb.height()), QColor("white"));
        for(int y = 0; y < pixmap_rb.height(); y++) {
            for(int x = 0; x < pixmap_rb.width(); x++) {
                const unsigned char b = qr->data[y * pixmap_rb.height() + x];
                if(b &0x01) {
                    painter.fillRect(QRect(x, y, 1, 1), QColor("black"));
                }
            }
        }

        //-1
        QRcode_free(qr);
    }
    return pixmap_rb;
}


static QString defStyleTable = R"(
                               QTableView,
                               QStandardItem{
                               border:none;
                               background-color:none;
                               color:none;
                               alternate-background-color:none;
                               }
                               QTableView:!enabled,
                               QStandardItem:!enabled{
                               alternate-background-color:none;
                               }
                               QHeaderView::section,
                               QHeaderView,
                               QTableView QTableCornerButton::section{
                               border:none; background-color: none;
                               }
                               QTableView QTableCornerButton,
                               QHeaderView::section{
                               color:white;
                               }
                               QTableView::item:selected{
                               background: none;
                               }

                               QTableView::item:!selected{
                               background: none;
                               }
                               )";
static QString defStyleControl = R"(
                                 QCheckBox{
                                 none;
                                 }
                                 QCheckBox::indicator:checked{
                                 none;
                                 }

                                 QCheckBox::indicator:unchecked {
                                 none;
                                 }
                                 QCheckBox::indicator:checked:!enabled {
                                 none;
                                 }

                                 QCheckBox::indicator:unchecked:!enabled{
                                 none;
                                 })";

static bool hasAr(const QString &text)
{
    for(int k = 0; k < text.count(); k ++) {
        if(text[k].direction() == QChar::DirAL) {
            return true;
        }
    }
    return false;
}

static QByteArray fileReadAll(const QString &path)
{
    QFile file(path);
    file.open(QFile::ReadOnly);
    return file.readAll();
}

tablePrintWidget::tablePrintWidget(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui_tablePrintWidget)
{
    ui->setupUi(this);

    //
    resize(1500, 800);
    ui->tableWidget->setItemDelegate(new contentItemDelegate(ui->tableWidget));
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    ui->tableWidget->resize(1000, 2000);
    QStringList titles = sale_detail.keys();
    header = new lds_tablewidget;
    header->horizontalHeader()->hide();
    header->verticalHeader()->hide();
    //    header->setContentSize(1, 1);
    header->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    header->setShowGrid(false);
    header->setFrameShape(QFrame::NoFrame);
    header->setItemDelegate(new txtItemDelegate(header));

    titles = QStringList() << "dishname" << "num" << "price" << "amount";
    for(int k = 0; k < titles.count(); k ++)
        header->appHorizontalHeader(titles[k], titles[k]);
    header->insertRow(0);
    for(int column = 0; column < header->columnCount(); column ++) {
        header->setText(0, column, titles.value(column));
    }

    content = new lds_tablewidget;
    content->horizontalHeader()->hide();
    content->verticalHeader()->hide();
    content->setContentSize(sale_detail.value(titles.value(0)).toStringList().count(), titles.count());
    content->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    content->setShowGrid(false);
    content->setFrameShape(QFrame::NoFrame);
    content->setItemDelegate(new contentItemDelegate(content));
    for(int k = 0; k < titles.count(); k ++)
        content->appHorizontalHeader(titles[k], titles[k]);
    for(int row = 0; row < content->rowCount(); row ++) {
        for(int column = 0; column < content->columnCount(); column ++) {
            QStringList l = sale_detail.value(titles.value(column)).toStringList();
            content->setText(row, column, l.value(column));
            content->setItemData(row, column, titles.value(column), _u_content_key);
        }
    }


    QString table = "sale_detail";
    headerAc = new QWidgetAction(this);
    QWidget *w = new QWidget;
    QGridLayout *layout = new QGridLayout;

    layout->addWidget(new QLabel("item"),   0, 1);
    layout->addWidget(new QLabel("move"),   0, 2);
    layout->addWidget(new QLabel("move"),   0, 3);
    layout->addWidget(new QLabel("row1"),   0, 4);
    layout->addWidget(new QLabel("row2"),   0, 5);
    layout->addWidget(new QLabel("width"),  0, 6);
    for(int k = 0; k < sale_detail.keys().count(); k ++){
        QCheckBox *check = new QCheckBox(w);
        QString key = sale_detail.keys().value(k);
        check->setText(key);

        QButtonGroup *bg = new QButtonGroup(this);
        QRadioButton *r1 = new QRadioButton;bg->addButton(r1);r1->setObjectName("r1");
        QRadioButton *r2 = new QRadioButton;bg->addButton(r2);r2->setObjectName("r2");
        QLineEdit *line = new QLineEdit;

        if(titles.contains(key))
        {
            r1->setChecked(true);
            line->setText("50");
            check->setChecked(true);
        }

        glayoutAddWidget(key, layout, check,                   1 + k, 1, SIGNAL(clicked(bool)), this, SLOT(headercheck(bool)));
        glayoutAddWidget(key, layout, createMinButton("<<"),   1 + k, 2, SIGNAL(clicked(bool)), this, SLOT(headermove0(bool)));
        glayoutAddWidget(key, layout, createMinButton(">>"),   1 + k, 3, SIGNAL(clicked(bool)), this, SLOT(headermove1(bool)));
        glayoutAddWidget(key, layout, r1,                      1 + k, 4, SIGNAL(clicked(bool)), this, SLOT(headerrow0(bool)));
        glayoutAddWidget(key, layout, r2,                      1 + k, 5, SIGNAL(clicked(bool)), this, SLOT(headerrow1(bool)));
        glayoutAddWidget(key, layout, line,                    1 + k, 6, SIGNAL(textChanged(QString)), this, SLOT(headerwidth(QString)));
    }
    glayoutAddWidget("TMP", layout, new QPushButton("appTo"),
                     1 + sale_detail.keys().count() ,
                     1, SIGNAL(clicked(bool)), this, SLOT(headerapp2content(bool)));
    w->setLayout(layout);
    headerAc->setDefaultWidget(w);

    this->setStyleSheet(defStyleTable);
    ui->tableWidget->setStyleSheet(defStyleTable);
    header->setStyleSheet(defStyleTable);
    content->setStyleSheet(defStyleTable);
    loadInit();

    ui->plainTextEdit->hide();

    ui->comboBox->addItems({"sale_head", "pay_detail", "pay_detail_paymode"});

    connect(ui->pushButton_column_switch, SIGNAL(clicked()), this, SLOT(tocolumn_switch()));
    connect(ui->pushButton_settings, SIGNAL(clicked()), this, SLOT(tosettings()));


}

tablePrintWidget::~tablePrintWidget()
{
    saveJson();
    delete ui;
}

void tablePrintWidget::add(int row, QString text, const QString &u1, QStringList buttons)
{
    ui->tableWidget->insertRow(row);
    ui->tableWidget->setItemData(row, "pre", u1, _u_pre_table);
    ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(u1).value<QColor>());

    ui->tableWidget->setText(row, "text", text);
    setButton(row, buttons);

    if(u1 == "receipt_head"
            || u1 == "sale_head"
            || u1 == "receipt_tail"
            ) {
        ui->tableWidget->setSpan(row, 2, 1, 2);
    }
    if(u1 == "pay_detail"
            || u1 == "pay_detail_paymode"
            ) {
        ui->tableWidget->setSpan(row, 1, 1, 2);
    }
}

void tablePrintWidget::addLine(int row)
{
    ui->tableWidget->insertRow(row);
    ui->tableWidget->setText(row, "text", QString(500, '-'));
    ui->tableWidget->setRowHeight(row, 5);
    ui->tableWidget->setTextElideMode(Qt::ElideNone);
    setSpans(row);
}

void tablePrintWidget::setButton(int row, QStringList buttons)
{
    QPushButton *add = 0;
    if(buttons.contains("del")) ui->tableWidget->setWidget(row, "del",          createMinButton("del"), SIGNAL(clicked()), this, SLOT(toDel()));
    if(buttons.contains("up")) ui->tableWidget->setWidget(row, "up",           createMinButton("up"), SIGNAL(clicked()), this, SLOT(toUp()));
    if(buttons.contains("down")) ui->tableWidget->setWidget(row, "down",         createMinButton("down"), SIGNAL(clicked()), this, SLOT(toDown()));
    if(buttons.contains("add")) ui->tableWidget->setWidget(row, "add", add =    createMinButton("add"));//, SIGNAL(clicked()), this, SLOT(toAdd()));

    qDebug() << __LINE__;
    QString table = ui->tableWidget->data(row, "pre", _u_pre_table).toString();
    QMap<QString, QVariant> map = receiptMap.value(table).toMap();
    QMenu *menu = new QMenu(add);
    if(table == "sale_detail") {
        menu->addAction(headerAc);
        connect(menu, SIGNAL(aboutToShow()), this, SLOT(toKeepHeaderWidht()));
    } else {
        for(QString k : map.keys()){
            QAction *ac = menu->addAction(k);
            ac->setData(table);
        }
        connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(toActionAdd(QAction *)));
    }

    qDebug() << __LINE__;
    if(add)
        add->setMenu(menu);
}

void tablePrintWidget::clearButton(int row)
{
    ui->tableWidget->setWidget(row, "del", 0);
    ui->tableWidget->setWidget(row, "up", 0);
    ui->tableWidget->setWidget(row, "down", 0);
    ui->tableWidget->setWidget(row, "add", 0);

}

void tablePrintWidget::swapSections(int row1, int row2)
{
    QList<QString> d;
    bool row1WillAddButton = false;
    bool row2WillAddButton = false;
    for(int k = 0; k < ui->tableWidget->columnCount(); k++) {
        QString text1 = ui->tableWidget->text(row1, k);
        if(ui->tableWidget->indexWidget(ui->tableWidget->index(row1, k)))
            row2WillAddButton = true;
        if(ui->tableWidget->indexWidget(ui->tableWidget->index(row2, k)))
            row1WillAddButton = true;

        ui->tableWidget->setText(row1, k, ui->tableWidget->text(row2, k));
        ui->tableWidget->setWidget(row1, k, 0);
        ui->tableWidget->setText(row2, k, text1);
        ui->tableWidget->setWidget(row2, k, 0);
    }
    if(row1WillAddButton)
        setButton(row1);
    if(row2WillAddButton)
        setButton(row2);
}

QByteArray tablePrintWidget::toJson()
{

    ///type
    //image
    //qrcode
    //text

    ///font
    //font-family
    //font-size

    ///align
    //align

    QByteArray json =
            "{"
            "\"column_width0\":0,"
            "\"column_width1\":0,"
            "\"column_width2\":0,"
            "\"font\":0,"
            "\"receipt_head\":[],"
            "\"sale_head\":[],"
            "\"sale_detail\":[],"
            "\"sale_detail_content\":[],"
            "\"pay_detail\":[],"
            "\"pay_detail_paymode\":[],"
            "\"receipt_tail\":[]"
            "}";
    JsonPathWriter w;
    w.parse(json);
    for(int k = 0; k < ui->tableWidget->rowCount(); k ++) {
        QString table = ui->tableWidget->data(k, "pre", _u_pre_table).toString();
        QString key = ui->tableWidget->data(k, "pre", _u_pre_key).toString();
        QString value = ui->tableWidget->text(k, "text");
        QString value2 = ui->tableWidget->text(k, "text2");
        QString value3 = ui->tableWidget->text(k, "text3");
        QString type = ui->tableWidget->data(k, "pre", _u_pre_img_type).toString();
        int align = ui->tableWidget->data(k, "text", Qt::TextAlignmentRole).toInt();

        if(table == "sale_detail") {
            for(int r = 0; r < header->rowCount(); r ++) {
                for(int c = 0; c < header->columnCount(); c ++) {
                    key = header->data(r, c, _u_header_key).toString();
                    value = header->text(r, c);
                    //                    if(key == "")
                    //                        continue;
                    w.append(table, QVariantMap{
                                 {"key", key},
                                 {"value", value},
                                 {"value2", value2},
                                 {"value3", value3},
                                 {"type", type},
                                 {"align", align},
                                 {"row", r},
                                 {"width", header->columnWidth(c)}
                             });
                }
            }
            continue;
        }

        if(table == "sale_detail_content") {
            int rcount = ui->tableWidget->data(k, "pre",_u_pre_content_rcount).toInt();
            for(int r = 0; r < rcount; r ++) {
                for(int c = 0; c < content->columnCount(); c ++) {
                    key =  content->data(r, c, _u_content_key).toString();
                    //                    if(key == "")
                    //                        continue;
                    w.append(table, QVariantMap{
                                 {"key", key},
                                 {"value", key},
                                 {"value2", value2},
                                 {"type", type},
                                 {"align", align},
                                 {"row", r},
                                 {"width", content->columnWidth(c)}
                             });
                }
            }
            continue;
        }
        if(key != "") {
            w.append(table, QVariantMap{
                         {"key", key},
                         {"value", value},
                         {"value2", value2},
                         {"value3", value3},
                         {"type", type},
                         {"align", align}
                     });
        }
    }
    w.setValue("column_width0", ui->tableWidget->columnWidth(1));
    w.setValue("column_width1", ui->tableWidget->columnWidth(2));
    w.setValue("column_width2", ui->tableWidget->columnWidth(3));
    w.setValue("font", ui->tableWidget->font());
    return w.toJson();
}

void tablePrintWidget::formJson(JsonPathReader &r)
{
    for(int r = ui->tableWidget->rowCount() - 1; r >= 0; r --) {
        QString table = ui->tableWidget->data(r, "pre", _u_pre_table).toString();
        if("sale_detail" == table) {
            continue;
        }
        if("sale_detail_content" == table) {
            continue;
        }
        ui->tableWidget->removeRow(r);
    }
    int row = 0;
    add_receipt_head(row, r);
    add_sale_head(row, r);
    addLine(row ++);//======================
    row++;add_sale_detail(r);//  sale_detail
    addLine(row ++);//======================
    row++;add_sale_detail_content(r);//  sale_detail_content
    addLine(row ++);//======================
    add_pay_detail(row, r);
    addLine(row ++);//======================
    add_pay_detail_paymode(row, r);
    add_receipt_tail(row, r);

    ui->tableWidget->setColumnWidth0("pre", 10);
    ui->tableWidget->setColumnWidth0("add",     buttonHeight);
    ui->tableWidget->setColumnWidth0("del",     buttonHeight);
    ui->tableWidget->setColumnWidth0("up",      buttonHeight);
    ui->tableWidget->setColumnWidth0("down",    buttonHeight);
    ui->tableWidget->setColumnWidth(1, r.value("column_width0").toInt());
    ui->tableWidget->setColumnWidth(2, r.value("column_width1").toInt());
    ui->tableWidget->setColumnWidth(3, r.value("column_width2").toInt());
    //ui->tableWidget->setFont(qvariant_cast<QFont>(r.value("font")));
    this->toSetFont(qvariant_cast<QFont>(r.value("font")));

    on_pushButton_adjust_clicked();
}

void tablePrintWidget::load()
{

}

void tablePrintWidget::loadInit()
{
    QString title0 = sale_detail.keys().value(0);

    ui->tableWidget->setContentSize(10, 4);
    ui->tableWidget->appHorizontalHeader("pre", "1");
    ui->tableWidget->appHorizontalHeader("text", "1");
    ui->tableWidget->appHorizontalHeader("text2", "1");
    ui->tableWidget->appHorizontalHeader("text3", "1");
    ui->tableWidget->appHorizontalHeader("del", "1");
    ui->tableWidget->appHorizontalHeader("up", "1");
    ui->tableWidget->appHorizontalHeader("down", "1");
    ui->tableWidget->appHorizontalHeader("add", "1");
    ui->tableWidget->setColumnWidth0("pre",     10);
    ui->tableWidget->setColumnWidth0("text",    250);
    ui->tableWidget->setColumnWidth0("add",     buttonHeight);
    ui->tableWidget->setColumnWidth0("del",     buttonHeight);
    ui->tableWidget->setColumnWidth0("up",      buttonHeight);
    ui->tableWidget->setColumnWidth0("down",    buttonHeight);
    ui->tableWidget->setColumnWidth0("text2",   250);

    add(0, "receipt_head", "receipt_head");
    add(1, "sale_head", "sale_head");
    addLine(2);//=======================
    add(3, "sale_detail", "sale_detail", {"add"});
    ui->tableWidget->setSpan(3, 1, 1, ui->tableWidget->columnCount() - 1 - 4);
    ui->tableWidget->setWidget(3, 1, header);
    header->setMinimumHeight(1 * 40);
    addLine(4);//=======================
    add(5, "sale_detail_content", "sale_detail_content", {""});
    ui->tableWidget->setSpan(5, 1, 1, ui->tableWidget->columnCount() - 1 - 4);
    ui->tableWidget->setWidget(5, 1, content);
    ui->tableWidget->setRowHeight(5, 5 * 40);
    ui->tableWidget->setItemData(5, "pre", 1, _u_pre_content_rcount);
    addLine(6);//=======================
    add(7, "pay_detail", "pay_detail");
    addLine(8);//=======================
    add(9, "pay_detail_paymode", "pay_detail_paymode");
    add(10, "receipt_tail", "receipt_tail");
}

void tablePrintWidget::setImage(int row, QString path)
{
    int column;
    int w;
    setSpans(row, &w, &column);
    QPixmap pixmap(path);
    ui->tableWidget->setItemData(row, "pre", "logo", _u_pre_img_type);
    ui->tableWidget->setItemData(row, column, pixmap, _u_img);
    ui->tableWidget->setText(row, "text", "");
    ui->tableWidget->setText(row, "text2", "");
    ui->tableWidget->setText(row, "text3", "");

}

void tablePrintWidget::setqrCode(int row, QString path)
{
    int column;
    int w;
    setSpans(row, &w, &column);
    QPixmap pixmap(get_rbcode(path.toLocal8Bit()));
    ui->tableWidget->setItemData(row, "pre", "qr_code", _u_pre_img_type);
    ui->tableWidget->setItemData(row, column, pixmap, _u_img);
    ui->tableWidget->setText(row, "text", "");
    ui->tableWidget->setText(row, "text2", "");
    ui->tableWidget->setText(row, "text3", "");
}

void tablePrintWidget::findAndResetqrCode(QByteArray code)
{
    int column = ui->tableWidget->fieldIndex("text");
    for(int row = 0; row < ui->tableWidget->rowCount(); row ++) {
        if(ui->tableWidget->data(row, 0, _u_pre_key) == "qr_code") {
            ui->tableWidget->setItemData(row, column, QPixmap(get_rbcode(code)), _u_img);
            break;
        }
    }
}

void tablePrintWidget::setSpans(int row, int *_w, int *_column)
{
    int c = 0;
    int w = 0;
    int column;
    for(int k = 0; k < ui->tableWidget->columnCount(); k ++) {
        if(ui->tableWidget->fieldNameList().value(k).startsWith("text")){
            c ++;
            w += ui->tableWidget->columnWidth(k);
        }
    }
    column = ui->tableWidget->fieldIndex("text");
    ui->tableWidget->setSpan(row, column, 1, c);

    if(_w)
        *_w = w;
    if(_column)
        *_column = column;
}

QPushButton *tablePrintWidget::createMinButton(const QString &text)
{
    QPushButton *b = new QPushButton(text);
    b->setFixedWidth(buttonHeight);
    return b;
}

void tablePrintWidget::glayoutAddWidget(QString key, QGridLayout *layout, QWidget *w, int row, int column, const char *signal, QObject *target, const char *member)
{
    headerWidgets[w] = key;
    layout->addWidget(w,row, column);
    connect(w, signal, target, member);
}

void tablePrintWidget::headerEnd()
{
    QString str0, str1;
    for(int k = 0; k < header->columnCount(); k ++) {
        str0 += header->text(0, k);
        str1 += header->text(1, k);
    }

    if(str0 == "") {
        header->removeRow(0);
    } else if(str1 == "") {
        header->removeRow(1);
    }

    //
    for(int c = header->columnCount() - 1; c >=0 ; c --) {
        QString tail;
        for(int r = 0; r < header->rowCount(); r ++) {
            tail += header->text(r, c);
        }
        if(tail == "") {
            header->rmHorizontalHeader(c);
            c--;
        } else  {
            break;
        }
    }
    //
    for(int k; k < header->rowCount(); k ++)
        header->setRowHeight(k, rowHeight0);
    ui->tableWidget->setRowHeight(headerIndex().row(), header->rowCount() * rowHeight0 + rowGap);
    //    headerapp2content(0);
}

QModelIndex tablePrintWidget::headerIndex()
{
    for(int k = 0; k < ui->tableWidget->rowCount(); k ++) {
        QModelIndex index = ui->tableWidget->index(k, 1);
        if(ui->tableWidget->indexWidget(index) == header)
            return index;
    }
    return QModelIndex();
}

QModelIndex tablePrintWidget::contentIndex()
{
    for(int k = 0; k < ui->tableWidget->rowCount(); k ++) {
        QModelIndex index = ui->tableWidget->index(k, 1);
        if(ui->tableWidget->indexWidget(index) == content)
            return index;
    }
    return QModelIndex();
}

void tablePrintWidget::add_receipt_head(int &row, JsonPathReader &r)
{
    QByteArray utext = "receipt_head";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = receipt_head.value(key).toString();//r.value(utext + "[%d/value", k).toString();
        QString type = r.value(utext + "[%d/type", k).toString();
        int align = r.value(utext + "[%d/align", k).toInt();
        //
        ui->tableWidget->insertRow(row);
        ui->tableWidget->setItemData(row, "pre", utext, _u_pre_table);
        ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(utext).value<QColor>());
        ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
        ui->tableWidget->setText(row, "text", value);
        ui->tableWidget->setItemData(row, "text",align, Qt::TextAlignmentRole);
        if(type == "logo")
            setImage(row, value);
        if(key != "tax_number")
            setSpans(row);
        if(key == "tax_number") {
            ui->tableWidget->setText(row, "text", key);
            ui->tableWidget->setText(row, "text2", value);
            ui->tableWidget->setSpan(row, 2, 1, 2);
        }

        setButton(row);
        row ++;
    }
}

void tablePrintWidget::add_sale_head(int &row, JsonPathReader &r)
{
    QByteArray utext = "sale_head";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = sale_head.value(key).toString();
        ui->tableWidget->insertRow(row);
        ui->tableWidget->setItemData(row, "pre", utext, _u_pre_table);
        ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(utext).value<QColor>());
        ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
        ui->tableWidget->setText(row, "text", key);
        ui->tableWidget->setText(row, "text2", value);
        setButton(row);
        ui->tableWidget->setSpan(row, 2, 1, 2);
        row ++;
    }
}

void tablePrintWidget::add_pay_detail(int &row, JsonPathReader &r)
{
    QByteArray utext = "pay_detail";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = pay_detail.value(key).toString();

        ui->tableWidget->insertRow(row);
        ui->tableWidget->setItemData(row, "pre", utext, _u_pre_table);
        ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(utext).value<QColor>());
        ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
        ui->tableWidget->setText(row, "text", key);
        ui->tableWidget->setText(row, "text3", value);
        setButton(row);
        ui->tableWidget->setSpan(row, 1, 1, 2);
        row ++;
    }
}

void tablePrintWidget::add_pay_detail_paymode(int &row, JsonPathReader &r)
{
    QByteArray utext = "pay_detail_paymode";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = pay_detail_paymode.value(key).toString();

        ui->tableWidget->insertRow(row);
        ui->tableWidget->setItemData(row, "pre", utext, _u_pre_table);
        ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(utext).value<QColor>());
        ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
        ui->tableWidget->setText(row, "text", key);
        ui->tableWidget->setText(row, "text3", value);
        setButton(row);
        ui->tableWidget->setSpan(row, 1, 1, 2);
        row ++;
    }
}

void tablePrintWidget::add_receipt_tail(int &row, JsonPathReader &r)
{
    QByteArray utext = "receipt_tail";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = receipt_tail.value(key).toString();
        QString value2 = r.value(utext + "[%d/value2", k).toString();
        QString value3 = r.value(utext + "[%d/value3", k).toString();
        QString type = r.value(utext + "[%d/type", k).toString();
        int align = r.value(utext + "[%d/align", k).toInt();
        //
        ui->tableWidget->insertRow(row);
        ui->tableWidget->setBackgroundColor(row, "pre", colorMap.value(utext).value<QColor>());
        ui->tableWidget->setItemData(row, "pre", utext, _u_pre_table);
        ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
        ui->tableWidget->setText(row, "text", value);
        if(key != "signature")
            ui->tableWidget->setItemData(row, "text",align, Qt::TextAlignmentRole);
        if(type == "qr_code") {
            setqrCode(row, value);
        }
        setSpans(row);

        setButton(row);
        row ++;
    }
}

void tablePrintWidget::add_sale_detail(JsonPathReader &r)
{
    int column0 = 0;
    int column1 = 0;
    int rowcount = 0;
    QByteArray utext = "sale_detail";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        int row = r.value(utext + "[%d/row", k).toInt();
        if(row == 0)
            column0 ++;
        if(row == 1)
            column1 ++;
        if(row == 0 && rowcount < 1) {
            rowcount = 1;
        }
        if(row == 1 && rowcount < 2) {
            rowcount = 2;
        }
    }
    header->setContentSize(0, 0);
    for(int k = 0; k < qMax(column0, column1); k ++) {
        header->appHorizontalHeader("1", "1");
    }
    for(int k = 0; k < rowcount; k ++) {
        header->insertRow(0);
    }

    //
    column0 = 0;
    column1 = 0;
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = sale_detail.value(key).toString();//r.value(utext + "[%d/value", k).toString();
        QString type = r.value(utext + "[%d/type", k).toString();
        int align = r.value(utext + "[%d/align", k).toInt();
        int row = r.value(utext + "[%d/row", k).toInt();
        int width = r.value(utext + "[%d/width", k).toInt();

        int c = 0;
        if(row == 0)
            c = column0 ++;
        if(row == 1)
            c = column1 ++;
        header->setItemData(row, c, key, _u_header_key);
        header->setText(row, c, key);
        header->setColumnWidth(c, width);
    }
}

void tablePrintWidget::add_sale_detail_content(JsonPathReader &r)
{
    lds_tablewidget vheader;

    int column0 = 0;
    int column1 = 0;
    int rowcount = 0;
    QByteArray utext = "sale_detail_content";
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        int row = r.value(utext + "[%d/row", k).toInt();
        if(row == 0)
            column0 ++;
        if(row == 1)
            column1 ++;
        if(row == 0 && rowcount < 1) {
            rowcount = 1;
        }
        if(row == 1 && rowcount < 2) {
            rowcount = 2;
        }
    }
    vheader.setContentSize(rowcount, qMax(column0, column1));

    //
    column0 = 0;
    column1 = 0;
    for(int k = 0; k < r.arrayCount(utext); k ++) {
        QString key = r.value(utext + "[%d/key", k).toString();
        QString value = r.value(utext + "[%d/value", k).toString();
        QString type = r.value(utext + "[%d/type", k).toString();
        int align = r.value(utext + "[%d/align", k).toInt();
        int row = r.value(utext + "[%d/row", k).toInt();
        int width = r.value(utext + "[%d/width", k).toInt();

        int c = 0;
        if(row == 0)
            c = column0 ++;
        if(row == 1)
            c = column1 ++;
        vheader.setItemData(row, c, key, _u_header_key);
        vheader.setColumnWidth(c, width);
    }
    //
    vheaderapp2content(&vheader);
}

QPixmap tablePrintWidget::scalePixmap(QModelIndex index, int cell_width)
{
    QPixmap img = qvariant_cast<QPixmap>(index.data(_u_img));
    if(!img.isNull()) {
        int w = cell_width * 0.4;
        img = img.scaledToHeight(w);
    }
    return img;
}

void tablePrintWidget::drawDocText(QPainter *painter, QFont font, QRect r, QString text)
{
    text = tablePrintWidget::receiptTrans.value(text, text);
    text = QFontMetrics(font).elidedText(text, Qt::ElideRight, r.width());

    QTextDocument doc(text);
    QTextOption opt = doc.defaultTextOption();
    opt.setWrapMode(QTextOption::NoWrap);
    doc.setDefaultFont(font);
    painter->save();
    doc.adjustSize();
    doc.setDefaultTextOption(opt);
    doc.setPageSize(QSize(r.width(), doc.size().height()));
    painter->translate(r.x(), r.y() + (r.height() - doc.size().height()) / 2);
    doc.drawContents(painter);
    painter->restore();
}

void tablePrintWidget::toDel()
{
    QPushButton *button = qobject_cast<QPushButton *>(this->sender());
    if(button == 0)
        return;
    QModelIndex index = ui->tableWidget->indexAt(button->pos());
    if(!index.isValid())
        return;
    ui->tableWidget->removeRow(index.row());
}

void tablePrintWidget::toUp()
{
    QPushButton *button = qobject_cast<QPushButton *>(this->sender());
    if(button == 0)
        return;

    int cur = ui->tableWidget->indexAt(button->mapToParent(QPoint(1, 1))).row();
    int pre = ui->tableWidget->indexAt(button->mapToParent(QPoint(1, 1)) - QPoint(0, ui->tableWidget->rowHeight(cur))).row();

    swapSections(cur, pre);
}

void tablePrintWidget::toDown()
{
    QPushButton *button = qobject_cast<QPushButton *>(this->sender());
    if(button == 0)
        return;
    int cur = ui->tableWidget->indexAt(button->mapToParent(QPoint(1, 1))).row();
    int after = ui->tableWidget->indexAt(button->mapToParent(QPoint(1, 1)) + QPoint(0, ui->tableWidget->rowHeight(cur))).row();

    swapSections(cur, after);
}

void tablePrintWidget::toAdd()
{
    //    QPushButton *button = qobject_cast<QPushButton *>(this->sender());
    //    if(button == 0)
    //        return;
    //    QModelIndex index = ui->tableWidget->indexAt(button->mapToParent(QPoint(1, 1)));
    //    if(!index.isValid())
    //        return;
    //    add(index.row() + 1, "", ui->tableWidget->data(index.row(), "pre", _u_pre_table).toString());
}

void tablePrintWidget::toActionAdd(QAction *a)
{
    QString table = a->data().toString();
    QString key = a->text();

    QMap<QString, QVariant> map = receiptMap.value(table).toMap();
    QModelIndex index = ui->tableWidget->indexAt((a->parentWidget()->parentWidget()->mapToParent(QPoint(1, 1))));
    int row = index.row();

    toAddItem(row, table, key);
}

void tablePrintWidget::toAddItem(int row, QString table, QString key)
{
    QMap<QString, QVariant> map = receiptMap.value(table).toMap();
    if(table == "sale_detail") {
        return;
    }
    //
    add(row + 1, "", table);
    //
    row ++;
    QString value = map.value(key).toString();
    ui->tableWidget->setItemData(row, "pre", key, _u_pre_key);
    ui->tableWidget->setText(row, "text", key);
    ui->tableWidget->setText(row, "text2", value);
    ui->tableWidget->setText(row, "text3", value);
    //
    if(table == "receipt_head"
            || table == "receipt_tail") {
        int w, column;

        if(key != "tax_number")
            setSpans(row, &w, &column);
        ui->tableWidget->setText(row, "text", value);
        ui->tableWidget->setText(row, "text2", "");
        ui->tableWidget->setText(row, "text3", "");
        if(key != "signature")
            ui->tableWidget->setItemData(row, column, Qt::AlignCenter, Qt::TextAlignmentRole);
        if(key == "tax_number") {
            ui->tableWidget->setText(row, "text", key);
            ui->tableWidget->setText(row, "text2", value);
            ui->tableWidget->setSpan(row, 2, 1, 2);
        }
        if(key == "second_title") {
            ui->tableWidget->setItemData(row, column, int(Qt::AlignHCenter | Qt::AlignTop), Qt::TextAlignmentRole);
        }
    }
    if(table == "sale_detail") {
        ui->tableWidget->setText(row, "text2", key);
    }
    if(key == "logo"){
        setImage(row, "C:/Users/cz/Pictures/logo.png");
    }
    if(key == "qr_code") {
        setqrCode(row, value);
    }
}

void tablePrintWidget::toCheckedItem(QStringList orders, QString table, QString key, bool checked)
{
    // remove
    if(!checked){
        int row = ui->tableWidget->indexOf(Qt::Vertical, 0, key, _u_pre_key);
        if(row < 0)
            goto end;
        QString delKey = ui->tableWidget->data(row, 0, _u_pre_key).toString();

        int tableCount = 0;
        for(int r = 0; r < ui->tableWidget->rowCount(); r ++) {
            QString k = ui->tableWidget->data(r, 0, _u_pre_key).toString();
            QString t = ui->tableWidget->data(r, 0, _u_pre_table).toString();
            if(t == table)
                tableCount ++;
        }
        for(int r = ui->tableWidget->rowCount() - 1; r >= 0  && tableCount > 1; r --) {
            QString k = ui->tableWidget->data(r, 0, _u_pre_key).toString();
            if(k == delKey) {
                ui->tableWidget->removeRow(r);
                tableCount --;
            }
        }
        goto end;
    }
    // add
    if(ui->tableWidget->indexOf(Qt::Vertical, 0, key, _u_pre_key) >= 0)
        goto end;

    {
        int find = -1;
        //pre find
        if(find == -1) {
            int cur = orders.indexOf(key);
            forever{
                cur --;
                if(cur < 0)
                    break;
                QString curValue = orders.value(cur);
                int index = ui->tableWidget->indexOf(Qt::Vertical, 0, curValue, _u_pre_key);
                if(index >= 0) {
                    find = index;
                    break;
                }
            }
        }
        //after find
        if(find == -1) {
            int cur = orders.indexOf(key);
            forever{
                cur ++;
                if(cur >= orders.count())
                    break;
                QString curValue = orders.value(cur);
                int index = ui->tableWidget->indexOf(Qt::Vertical, 0, curValue, _u_pre_key);
                if(index >= 0) {
                    find = index;
                    break;
                }
            }
            if(find != -1)
                find --;
        }
        //    find ++;

        //toAddItem will find ++
        toAddItem(find, table, key);
    }

end:
    on_pushButton_adjust_clicked();
    QTimer::singleShot(0, this, SLOT(emitImageReresh()));
}

void tablePrintWidget::headercheck(bool checked)
{
    qDebug()<< __FILE__ << __LINE__;
    QString key = headerWidgets[sender()];
    int r = 0;
    int k = header->indexOfHorizontal(0, key);
    if(k < 0) {
        k = header->indexOfHorizontal(1, key);
        r = 1;
    }
    if(k >= 0 && !checked) {
        header->setText(r, k, "");
        if(header->text(0, k) == "" && header->text(1, k) == "")
            header->rmHorizontalHeader(k);

        goto end;
    }
    if(k < 0 && checked) {
        header->appHorizontalHeader(key, key);
        if(header->rowCount() == 0)
            header->insertRow(0);
        header->setItemData(0, key, key, _u_header_key);
        header->setText(0, key, key);
    }

end:
    headerEnd();
}

void tablePrintWidget::headermove0(bool)
{
    QString key = headerWidgets[sender()];
    int r = 0;
    int k = header->indexOfHorizontal(0, key, _u_header_key);
    if(k < 0) {
        k = header->indexOfHorizontal(1, key, _u_header_key);
        r = 1;
    }
    if(k == 0)
        goto end;

    {
        headerSwitch(r, k, r, k -1);
    }
end:
    headerEnd();
}

void tablePrintWidget::headermove1(bool)
{
    QString key = headerWidgets[sender()];
    int r = 0;
    int k = header->indexOfHorizontal(0, key, _u_header_key);
    if(k < 0) {
        k = header->indexOfHorizontal(1, key, _u_header_key);
        r = 1;
    }
    if(k == header->columnCount())
        goto end;

    {
        headerSwitch(r, k, r, k + 1);
    }
end:
    headerEnd();
}

void tablePrintWidget::headerrow0(bool checked)
{
    QString key = headerWidgets[sender()];
    if(!checked)
        goto end;

    if(header->rowCount() == 0) {
        goto end;
    }
    if(header->rowCount() == 1) {
        header->insertRow(1);
    }

    {
        int k = header->indexOfHorizontal(1, key, _u_header_key);

        headerSwitch(0, k, 1, k);
    }
end:
    headerEnd();
}

void tablePrintWidget::headerrow1(bool checked)
{
    QString key = headerWidgets[sender()];
    if(!checked)
        goto end;

    if(header->rowCount() == 1) {
        header->insertRow(1);
    }

    {
        int k = header->indexOfHorizontal(0, key, _u_header_key);
        headerSwitch(0, k, 1, k);
    }
end:
    headerEnd();
}

void tablePrintWidget::headerwidth(QString w)
{
    qDebug() << __LINE__ << qApp->focusWidget()->metaObject()->className();
    if(qApp->focusWidget()->metaObject()->className() != QString("QLineEdit"))
        return;
    qDebug() << __LINE__ << qApp->focusWidget()->metaObject()->className();
    QString key = headerWidgets[sender()];
    int r = 0;
    int k = header->indexOfHorizontal(0, key);
    if(k < 0) {
        k = header->indexOfHorizontal(1, key);
        r = 1;
    }
    if(k < 0)
        goto end;
    header->setColumnWidth(k, w.toInt());

end:
    headerEnd();
}

void tablePrintWidget::headerapp2content(bool)
{
    vheaderapp2content(header);
}

void tablePrintWidget::vheaderapp2content(lds_tablewidget *header)
{
    content->setContentSize(0, 0);

    for(int c = 0 ; c < header->columnCount(); c ++) {
        content->appHorizontalHeader("1", "1");
        content->setColumnWidth(c, header->columnWidth(c));
    }
    //
    int content_row = 0;
    for(int k = 0; k < sale_detail.begin().value().toStringList().count(); k ++) {
        for(int r = 0; r < header->rowCount(); r ++, content_row ++) {
            content->insertRow(content_row);
            for(int c = 0; c < header->columnCount(); c ++){
                QString key = header->data(r, c, _u_header_key).toString();
                if(key == "")
                    continue;
                QString value = sale_detail.value(key).toStringList().value(k);
                //                bool ok = false;
                //                QString num = QString().sprintf("%.02f", value.toDouble(&ok));
                //                if(ok)
                //                    value = num;
                content->setText(content_row, c, value);
                content->setItemData(content_row, c, key, _u_content_key);
            }
        }
    }
    //
    QModelIndex index = contentIndex();
    int row = index.row();
    ui->tableWidget->setItemData(row, "pre", header->rowCount(), _u_pre_content_rcount);


    for(int k; k < content->rowCount(); k ++)
        content->setRowHeight(k, rowHeight0);
    ui->tableWidget->setRowHeight(contentIndex().row(), content->rowCount() * rowHeight0 + rowGap);
}

void tablePrintWidget::toKeepHeaderWidht()
{
    foreach(QObject *obj, headerWidgets.keys()) {

        if(qobject_cast<QLineEdit *>(obj)) qobject_cast<QLineEdit *>(obj)->setText("50");
        if(qobject_cast<QRadioButton *>(obj)) qobject_cast<QRadioButton *>(obj)->setChecked(false);
        if(qobject_cast<QCheckBox *>(obj)) qobject_cast<QCheckBox *>(obj)->setChecked(false);
    }

    for(int r = 0; r < header->rowCount(); r ++) {
        for(int c = 0; c < header->columnCount(); c ++){
            QString key = header->data(r, c, _u_header_key).toString();
            QString value = header->text(r, c);
            if(key == "")
                continue;
            foreach(QObject *obj, headerWidgets.keys(key)) {
                QLineEdit *line = qobject_cast<QLineEdit *>(obj);
                if(line) {
                    line->setText(QString::number(header->columnWidth(c)));
                }
                QRadioButton *rb = qobject_cast<QRadioButton*>(obj);
                if(rb) {
                    qDebug() << key << value << r;
                    if(rb->objectName() == "r1" && r == 0){
                        qDebug() << key << "r1" << "checked";
                        rb->setChecked(true);
                    }
                    if(rb->objectName() == "r2" && r == 1){
                        qDebug() << key << "r2" << "checked";
                        rb->setChecked(true);
                    }
                }
                QCheckBox *check = qobject_cast<QCheckBox*>(obj);
                if(check) {
                    check->setChecked(true);
                }
            }
        }
    }
}

void tablePrintWidget::toSetFont(QFont f)
{
    //    this->setFont(f);
    ui->tableWidget->setFont(f);
    header->setFont(f);
    content->setFont(f);
    on_pushButton_adjust_clicked();
}

void tablePrintWidget::emitImageReresh()
{
    emit imgRefresh(printerPixmap(true));
}

void tablePrintWidget::on_pushButton_toJson_clicked()
{
    saveJson();
    ui->plainTextEdit->setPlainText(toJson());
}

void tablePrintWidget::on_pushButton_reset_clicked()
{
    QByteArray json;
    QFile file(fastfd_defaultSetting);
    if(file.open(QFile::ReadOnly))
        json = file.readAll();
    else
        json = defaultSetting;
    JsonPathReader r(json);
    formJson(r);
    on_pushButton_adjust_clicked();
}

void tablePrintWidget::on_pushButton_adjust_clicked()
{
    ui->tableWidget->setShowGrid(false);

    int w = ui->tableWidget->columnWidth(1) + ui->tableWidget->columnWidth(2) + ui->tableWidget->columnWidth(3);
    for(int k = 0; k < ui->tableWidget->rowCount(); k ++) {
        ui->tableWidget->setRowHeight(k, rowHeight0);
        QString table = ui->tableWidget->data(k, "pre", _u_pre_table).toString();
        QString key = ui->tableWidget->data(k, "pre", _u_pre_key).toString();
        if(table == "")
            ui->tableWidget->setRowHeight(k, lineHeight);

        if(table == "receipt_head") {
            QString text = ui->tableWidget->text(k, "text");
            int height = QFontMetrics(ui->tableWidget->font()).boundingRect(QRect(0, 0, w, 10), Qt::TextWordWrap, text).height();
            ui->tableWidget->setRowHeight(k, height);
        }
        if(key == "second_title") {
            ui->tableWidget->setRowHeight(k, rowHeight0 * 2);
        }
        QPixmap img = qvariant_cast<QPixmap>(ui->tableWidget->data(k, 1, _u_img));
        if(!img.isNull()) {
            int h = scalePixmap(ui->tableWidget->index(k, 1),
                                ui->tableWidget->columnWidth(1) +
                                ui->tableWidget->columnWidth(2) +
                                ui->tableWidget->columnWidth(3)
                                ).height();
            ui->tableWidget->setRowHeight(k, h);
        }
    }

    //content
    int contentHeight = 0;
    for(int k = 0; k < content->rowCount(); k ++) {
        int rowHeightx = rowHeight0;
        for(int c = 0; c < content->columnCount(); c ++) {
            if(content->text(k, c).contains("\n")) {
                rowHeightx = 2.2 * rowHeight0;
                break;
            }
        }
        content->setRowHeight(k, rowHeightx);
        contentHeight += rowHeightx;
    }
    ui->tableWidget->setRowHeight(contentIndex().row(), contentHeight + rowGap);

    //header
    for(int k = 0; k < header->rowCount(); k ++)
        header->setRowHeight(k, rowHeight0);
    ui->tableWidget->setRowHeight(headerIndex().row(), header->rowCount() * rowHeight0 + rowGap);

    ui->tableWidget->selectionModel()->clearSelection();
    header->selectionModel()->clearSelection();
    content->selectionModel()->clearSelection();
}

void tablePrintWidget::on_pushButton_fromJson_clicked()
{
    QByteArray json = ui->plainTextEdit->toPlainText().toLocal8Bit();
    JsonPathReader r(json);

    formJson(r);
}

void tablePrintWidget::on_pushButton_pix_clicked()
{
    QLabel *label = new QLabel;
    label->setPixmap(printerPixmap().scaledToWidth(400));
    label->resize(label->pixmap()->size());
    label->show();
}


QPixmap tablePrintWidget::printerPixmap(bool forTest)
{
    int w = ui->tableWidget->columnWidth(1) + ui->tableWidget->columnWidth(2) + ui->tableWidget->columnWidth(3);
    int x = ui->tableWidget->columnWidth(0);
    int y = 0;
    int h = 0;
    for(int row = 0; row < ui->tableWidget->rowCount(); row ++)
        h += ui->tableWidget->rowHeight(row);
    if(forTest) {
        x = 0;
        w += ui->tableWidget->columnWidth(0);
    }
    return (ui->tableWidget->viewport()->grab(QRect(x, y, w, h)).scaledToWidth(560));
}

void tablePrintWidget::saveJson()
{
    QFile file(saveFilePath);
    file.open(QFile::WriteOnly);
    QTextStream in(&file);
    in.setCodec("UTF-8"); // 设置文件的编码格式为UTF-8
    in << toJson();
    file.close();
}

void tablePrintWidget::headerSwitch(int r, int c, int r1, int c1)
{
    QString key1 = header->text(r1, c1);
    QVariant value1 = header->data(r1, c1, _u_header_key);
    QString key = header->text(r, c);
    QVariant value = header->data(r, c, _u_header_key);

    header->setText(r1, c1,       key);
    header->setItemData(r1, c1,   value, _u_header_key);

    header->setText(r, c,       key1);
    header->setItemData(r, c,   value1, _u_header_key);
}

int tablePrintWidget::wordWrapHeight(QString text, int w, QFont font)
{
    QFontMetrics fm(font);
    return fm.boundingRect(QRect(0,0,w,100), Qt::TextWordWrap, text).height();
}

static bool saveFilePathIsVlid()
{
    QByteArray json = fileReadAll(tablePrintWidget::saveFilePath);
    return 0 < JsonPathReader(json).arrayCount("pay_detail_paymode");

}
void tablePrintWidget::initRecipt()
{
    QByteArray json;
/*    if(QFile::exists(saveFilePath) && saveFilePathIsVlid()) {
        json = fileReadAll(saveFilePath);
    } else */if(QFile::exists("userdata/settings/print/table_receipt/def.txt")) {
        json = fileReadAll("userdata/settings/print/table_receipt/def.txt");
    } else {
        json = defaultSetting;
    }
    JsonPathReader r(json);
    formJson(r);
}

void tablePrintWidget::on_pushButton_select_font_clicked()
{
    QFontDialog *dialog = new QFontDialog(ui->tableWidget->font(), this);
    connect(dialog, SIGNAL(currentFontChanged(QFont)), this , SLOT(toSetFont(QFont)));
    dialog->open();
}

void tablePrintWidget::on_pushButton_printer_clicked()
{
    QByteArray pHex;
    QImage img = printerPixmap().toImage();


    Bmp_info::pic2Ins(img, pHex);
    Printer_POS_win_POS80 printer;
    printer.tryOpen("POS80");
    printer.writedirect(pHex);
    printer.writedirect(QString(10, '\n').toLocal8Bit());
    printer.writeHex("1B6405 1D5601");//走纸5x， 切纸

    img.save("img.png");
}

void tablePrintWidget::tocolumn_switch()
{

}

void tablePrintWidget::tosettings()
{
    tablePrintSettings *d = new tablePrintSettings(this);
    d->exec();
    saveJson();
}

void tablePrintWidget::initreceiptMap()
{
    qDebug() << __LINE__ << pay_detail;
    qDebug() << __LINE__ << pay_detail_paymode;
    qDebug() << __LINE__ << sale_detail;
    //pay_detail
    for(QMap<QString, QVariant>::iterator k = pay_detail.begin(); k != pay_detail.end(); k ++) {
        k->setValue(QString().sprintf("%.02f", k.value().toDouble()));
    }
    //pay_detail_paymode
    for(QMap<QString, QVariant>::iterator k = pay_detail_paymode.begin(); k != pay_detail_paymode.end(); k ++) {
        k->setValue(QString().sprintf("%.02f", k.value().toDouble()));
    }
    //sale_detail
    {
        QStringList &numPtr = *reinterpret_cast<QStringList *>(&sale_detail["num"]);
        for(int k = 0; k < numPtr.count(); k ++) {
            numPtr[k] = QString().sprintf("%.02f",numPtr[k].toDouble());
        }
        QStringList &pricePtr = *reinterpret_cast<QStringList *>(&sale_detail["price"]);
        for(int k = 0; k < pricePtr.count(); k ++) {
            pricePtr[k] = QString().sprintf("%.02f",pricePtr[k].toDouble());
        }
        QStringList &amountPtr = *reinterpret_cast<QStringList *>(&sale_detail["amount"]);
        for(int k = 0; k < amountPtr.count(); k ++) {
            amountPtr[k] = QString().sprintf("%.02f",amountPtr[k].toDouble());
        }
    }

    qDebug() << __LINE__ << pay_detail;
    qDebug() << __LINE__ << pay_detail_paymode;
    qDebug() << __LINE__ << sale_detail;

    receiptMap = {{"receipt_head",          QVariant::fromValue(receipt_head)},
                  {"sale_head",             QVariant::fromValue(sale_head)},
                  {"sale_detail",           QVariant::fromValue(sale_detail)},
                  {"sale_detail_content",   QVariant::fromValue(sale_detail_content)},
                  {"pay_detail",            QVariant::fromValue(pay_detail)},
                  {"pay_detail_paymode",    QVariant::fromValue(pay_detail_paymode)},
                  {"receipt_tail",          QVariant::fromValue(receipt_tail)}
                 };
}


void contentItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt;
    opt = option;
    initStyleOption(&opt, index);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
    const QWidget *widget = option.widget;
#else
    const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option);
    const QWidget *widget = v3? v3->widget : 0;
#endif
    QStyle *style = widget? widget->style() : QApplication::style();

    bool ok = false;
    QString text = index.data(Qt::DisplayRole).toString();
    text.toDouble(&ok);
    if(ok)
        ok = text.contains(".");
    if(ok) {
        opt.text = "";
    }
    QPixmap img = qvariant_cast<QPixmap>(index.data(tablePrintWidget::_u_img));
    if(!img.isNull())
        opt.text = "";
    if(!ok){
        opt.text = tablePrintWidget::receiptTrans.value(text, text);
        opt.text.replace('\n', "\u2028");
        if(hasAr(opt.text))
            opt.font.setBold(true);
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
    }

    if(ok) {
        QFont numFont = opt.font;
        numFont.setPointSize(numFont.pointSize() * 0.9);
        int w = qMax(QFontMetrics(numFont).width(text), QFontMetrics(numFont).width("999.99"));
        int off = opt.rect.width()  - w;
        painter->setFont(numFont);
        painter->drawText(opt.rect.adjusted(0, 0, -off, 0),
                          Qt::AlignVCenter | Qt::AlignRight, text);
    }
    if(!img.isNull()) {
        img = tablePrintWidget::scalePixmap(index, opt.rect.width());
        painter->drawPixmap(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, img.size(), opt.rect), img);
    }
}

void txtItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt;
    opt = option;
    initStyleOption(&opt, index);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
    const QWidget *widget = option.widget;
#else
    const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option);
    const QWidget *widget = v3? v3->widget : 0;
#endif
    QStyle *style = widget? widget->style() : QApplication::style();

    QString text = opt.text;
    //    opt.text = "";
    //    opt.font;
    text = tablePrintWidget::receiptTrans.value(text, text);
    opt.text = QFontMetrics(opt.font).elidedText(text, Qt::ElideRight, opt.rect.width());
    if(hasAr(opt.text))
        opt.font.setBold(true);
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);

    //    tablePrintWidget::drawDocText(painter, opt.font, opt.rect, text);
}
